﻿using Lucene.Net.Index;
using Lucene.Net.Search;
using System;

namespace Tunynet.Search
{
    /// <summary>
    /// 
    /// </summary>
    public class SearcherManager
    {
        /// <summary>
        /// 
        /// </summary>
        private IndexSearcher a;
        /// <summary>
        /// 
        /// </summary>
        private IndexWriter b;
        /// <summary>
        /// 
        /// </summary>
        private object c = new object();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        public SearcherManager(IndexWriter writer)
        {
            this.b = writer;
            this.a = new IndexSearcher(writer.GetReader());
        }

        /// <summary>
        /// 
        /// </summary>
        public void Reopen()
        {
            lock (this.c)
            {
                IndexSearcher indexSearcher = this.a;
                try
                {
                    indexSearcher.GetIndexReader().IncRef();
                    IndexReader indexReader = indexSearcher.GetIndexReader();
                    if (!indexReader.IsCurrent())
                    {
                        IndexReader indexReader2 = indexReader.Reopen();
                        if (indexReader2 != indexReader)
                        {
                            this.a.GetIndexReader().DecRef();
                            this.a = new IndexSearcher(indexReader2);
                        }
                    }
                }
                finally
                {
                    indexSearcher.GetIndexReader().DecRef();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IndexSearcher GetSearcher()
        {
            IndexSearcher result;
            lock (this.c)
            {
                this.a.GetIndexReader().IncRef();
                result = this.a;
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        public void ReleaseSearcher()
        {
            this.ReleaseSearcher(this.a);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="searcher"></param>
        public void ReleaseSearcher(IndexSearcher searcher)
        {
            lock (this.c)
            {
                searcher.GetIndexReader().DecRef();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Close()
        {
            this.ReleaseSearcher();
            this.a = null;
        }
    }
}
